/**
 * @file shell.c
 * @author MTF-1
 *
 * @date 23-01-2011 DD-MM-YYYY
 * @version 0.8
 *
 * @section DESCRIPTION
 *
 * Client interface/shell.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tools.h"
#include "connectionCmds.h"
#include "fileOperationsCmds.h"
#include "fileTransferCmds.h"
#include "otherCmds.h"

#define ERROR 1
#define NOERROR 0
#define TRUE 1
#define FALSE 0
#define MAXPARS 4
#define CMDLINELEN 255

typedef unsigned char bool;

/*Internal function prototyping*/
int chkPar(char *ptr_sPars[], int iStartIndex, int iParAmount, bool bOptionalPars);
int execCommand(char *ptr_sCmdPars[]);

/**
 * Main function: ask and execute commands.
 *
 * @param argc Amount of args.
 * @param argv List of args.
 * @return -1 on error and 0 on no error.
 * @author Rik Janssen
 */
int main(int argc, char** argv)
{
    char sCmdLine[CMDLINELEN], *ptr_sCmdPars[MAXPARS];
    int i;

    printf("--- 3RGK CLIENT ---\n");

    /*Eternal loop*/
    while(1)
    {
        /*Reset command and pars to NULL*/
        for(i=0; i<MAXPARS; i++)
        {
            ptr_sCmdPars[i] = 0;
        }

        /*Get input from command line*/
        if(getCommand(sCmdLine, CMDLINELEN))
        {
            fprintf(stderr, "Error when reading command!\n");
        }
        else
        {
            /*Seperate command and parameters*/
            split(sCmdLine, ptr_sCmdPars, MAXPARS, ' ');

            /*Execute command with pars*/
            if(execCommand(ptr_sCmdPars))
            {
                fprintf(stderr, "Error when executing command: %s.\n", ptr_sCmdPars[0]);
            }
        }
    }

    return NOERROR; /*never gets here -> see exit command*/
}

/**
 * Check if the correct amount of -required- parameters are present
 *
 * @param ptr_sPars list of entered parameters.
 * @param iStartIndex start index number of the list of entered parameters (first parameter to check).
 * @param iParAmount amount of -required- parameters to a command.
 * @param bOptionalPars are there any optional parameters to a command.
 * @return 1 on error (to few or to many parameters are present) and 0 on no error (correct amount of parameters are present)
 * @author Rik Janssen
 */
int chkPar(char *ptr_sPars[], int iStartIndex, int iParAmount, bool bOptionalPars)
{
    /*check if all required parameters are present*/
    for(iStartIndex; iStartIndex<=iParAmount; iStartIndex++)
    {
        if(ptr_sPars[iStartIndex] == 0)
        {
            return ERROR;
        }
    }

    /*Check if optional parameters is FALSE*/
    if(!bOptionalPars)
    {
        /*Check if there are to many parameters present*/
        if(ptr_sPars[iStartIndex] != 0)
        {
            return ERROR;
        }
    }

    /*correct amount of parameters are present*/
    return NOERROR;
}

/**
 * Execute command with pars.
 *
 * @param ptr_sCmdPars Pointer to command and pars.
 * @return 1 on error and 0 on no error.
 * @author Rik Janssen, Robbert Busser
 */
int execCommand(char *ptr_sCmdPars[])
{
    int iCmdNum = -1; /*Default is unknown command number*/

    getCmdNum(ptr_sCmdPars[0], &iCmdNum);

    /*Execute command number*/
    switch(iCmdNum)
    {
        case 0:
            if(chkPar(ptr_sCmdPars, 1, 0, FALSE))
            {
                fprintf(stderr, "This parameter is not supported use \"help exit\".\n");
            }
            else
            {
                cmdExit();
            }
            break;
        case 1:
            if(chkPar(ptr_sCmdPars, 1, 1, TRUE))
            {
                fprintf(stderr, "This parameter is not supported use \"help connect\".\n");
            }
            else
            {
                cmdConnect(ptr_sCmdPars[1], ptr_sCmdPars[2]);
            }
            break;
        case 2:
            if(chkPar(ptr_sCmdPars, 1, 0, FALSE))
            {
                fprintf(stderr, "This parameter is not supported use \"help disconnect\".\n");
            }
            else
            {
                cmdDisconnect();
            }
            break;
        case 3:
            if(chkPar(ptr_sCmdPars, 1, 0, FALSE))
            {
                fprintf(stderr, "This parameter is not supported use \"help info\".\n");
            }
            else
            {
                cmdInfo();
            }
            break;
        case 4:
            if(chkPar(ptr_sCmdPars, 1, 0, TRUE))
            {
                fprintf(stderr, "This parameter is not supported use \"help help\".\n");
            }
            else
            {
                cmdHelp(ptr_sCmdPars[1]);
            }
            break;
        case 5:
            if(chkPar(ptr_sCmdPars, 1, 2, FALSE))
            {
                fprintf(stderr, "This parameter is not supported use \"help upload\".\n");
            }
            else
            {
                cmdUpload(ptr_sCmdPars[1], ptr_sCmdPars[2]);
            }
            break;
        case 6:
            if(chkPar(ptr_sCmdPars, 1, 2, FALSE))
            {
                fprintf(stderr, "This parameter is not supported use \"help download\".\n");
            }
            else
            {
                cmdDownload(ptr_sCmdPars[1], ptr_sCmdPars[2]);
            }
            break;
        case 7:
            if(chkPar(ptr_sCmdPars, 1, 0, FALSE))
            {
                fprintf(stderr, "This parameter is not supported use \"help list\".\n");
            }
            else
            {
                cmdList();
            }
            break;
        case 8:
            if(chkPar(ptr_sCmdPars, 1, 1, FALSE))
            {
                fprintf(stderr, "This parameter is not supported use \"help remove\".\n");
            }
            else
            {
                cmdRemove(ptr_sCmdPars[1]);
            }
            break;
        case 9:
            if(chkPar(ptr_sCmdPars, 1, 1, FALSE))
            {
                fprintf(stderr, "This parameter is not supported use \"help cd\".\n");
            }
            else
            {
                cmdCd(ptr_sCmdPars[1]);
            }
            break;
        case 10:
            if(chkPar(ptr_sCmdPars, 1, 0, FALSE))
            {
                fprintf(stderr, "This parameter is not supported use \"help clear\".\n");
            }
            else
            {
                cmdClear();
            }
            break;
        default:
            return ERROR; /*Unknown command number*/
    }

    return NOERROR;
}
